// * 问题分析

//   * 位宽转换，转换比为1:4，上下级用握手方式传输数据，要充分考虑反压情况
// * 输入

//   * din_valid, din_ready, din[4:0]
// * 输出

//   * dout_valid, dout_ready, dout[19:0]
//   * 输出信号寄存1拍，则输出比输入信号延迟1拍
// * 中间寄存器

//   * holding[2:0]
// * 过程

//   * holding负责计算din握手成功次数，即上级传入多少tick

//     * 那么如果位宽拼接是1:4，则希望valid=(holding==4)
//     * din_ready：

//       * 如果dout_valid拉高时dout_ready拉低，则数据无法传输，为了防止dout数据被冲毁，此时din_ready需拉低，即din_ready=dout_ready；
//       * 但是如果dout_valid未拉高，则数据未拼接完成，仍有承载能力，可以继续接收上级数据，即din_ready=!dout_valid；
//       * 那么合并即可：din_ready=!dout_valid | dout_ready。

module top #(
           parameter word_len = 66
       )(
           input clk, arst,
           input [5 * word_len - 1: 0] din,
           input din_valid,
           input dout_ready,

           output din_ready,
           output dout_valid,
           output reg [20 * word_len - 1: 0] dout
       );

reg [2: 0] holding;

assign dout_valid = holding[2];
assign din_ready = (!dout_valid | dout_ready);


always @(posedge clk or negedge arst)
	begin
		if (!arst)
			begin
				dout <= 0;
				holding <= 0;
			end
		else
			begin
				if (din_ready & din_valid)
					begin
						dout <= {din, dout[20 * word_len - 1: 5 * word_len]};
						if (dout_valid)
							holding <= 3'd1;
						else
							holding <= holding + 3'd1;
					end
				else
					begin
						if (dout_valid & dout_ready)
							holding <= 0;
					end
			end
	end
endmodule

